﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpMUD.Framework.Security;

namespace SharpMUD.Framework.Services.Security
{
    /// <remarks>Based on System.Web.Security.MembershipProvider</remarks>
    public interface IUserProvider
    {
        ///
        /// <summary>
        ///     Indicates whether the User provider is configured to allow users to
        ///     reset their passwords.</summary>
        ///
        /// <returns>
        ///     true if the User provider supports password reset; otherwise, false.
        ///     The default is true.</returns>
        bool EnablePasswordReset { get; }

        ///
        /// <summary>
        ///     Indicates whether the User provider is configured to allow users to
        ///     retrieve their passwords.</summary>
        ///
        /// <returns>
        ///     true if the User provider is configured to support password retrieval;
        ///     otherwise, false. The default is false.</returns>
        bool EnablePasswordRetrieval { get; }

        ///
        /// <summary>
        ///     Gets the number of invalid password or password-answer attempts allowed before
        ///     the User user is locked out.</summary>
        ///
        /// <returns>
        ///     The number of invalid password or password-answer attempts allowed before
        ///     the User user is locked out.</returns>
        int MaxInvalidPasswordAttempts { get; }

        ///
        /// <summary>
        ///     Gets the minimum number of special characters that must be present in a valid
        ///     password.</summary>
        ///
        /// <returns>
        ///     The minimum number of special characters that must be present in a valid
        ///     password.</returns>
        int MinRequiredNonAlphanumericCharacters { get; }

        ///
        /// <summary>
        ///     Gets the minimum length required for a password.</summary>
        ///
        /// <returns>
        ///     The minimum length required for a password.</returns>
        int MinRequiredPasswordLength { get; }

        ///
        /// <summary>
        ///     Gets the number of minutes in which a maximum number of invalid password
        ///     or password-answer attempts are allowed before the User user is locked
        ///     out.</summary>
        ///
        /// <returns>
        ///     The number of minutes in which a maximum number of invalid password or password-answer
        ///     attempts are allowed before the User user is locked out.</returns>
        int PasswordAttemptWindow { get; }

        ///
        /// <summary>
        ///     Gets a value indicating the format for storing passwords in the User
        ///     data store.</summary>
        ///
        /// <returns>
        ///     One of the UserPasswordFormat values indicating
        ///     the format for storing passwords in the data store.</returns>
        UserPasswordFormat PasswordFormat { get; }

        ///
        /// <summary>
        ///     Gets the regular expression used to evaluate a password.</summary>
        ///
        /// <returns>
        ///     A regular expression used to evaluate a password.</returns>
        string PasswordStrengthRegularExpression { get; }

        ///
        /// <summary>
        ///     Gets a value indicating whether the User provider is configured to
        ///     require the user to answer a password question for password reset and retrieval.</summary>
        ///
        /// <returns>
        ///     true if a password answer is required for password reset and retrieval; otherwise,
        ///     false. The default is true.</returns>
        bool RequiresQuestionAndAnswer { get; }

        ///
        /// <summary>
        ///     Gets a value indicating whether the User provider is configured to
        ///     require a unique e-mail address for each user name.</summary>
        ///
        /// <returns>
        ///     true if the User provider requires a unique e-mail address; otherwise,
        ///     false. The default is true.</returns>
        bool RequiresUniqueEmail { get; }

        /// <summary>
        ///     Occurs when a user is created, a password is changed, or a password is reset.</summary>
        event UserValidatePasswordEventHandler ValidatingPassword;

        /// <summary>
        ///     Processes a request to update the password for a User user.</summary>
        ///
        /// Parameters:
        ///   username:
        ///     The user to update the password for.
        ///
        ///   oldPassword:
        ///     The current password for the specified user.
        ///
        ///   newPassword:
        ///     The new password for the specified user.
        ///
        /// <returns>
        ///     true if the password was updated successfully; otherwise, false.</returns>
        bool ChangePassword(string username, string oldPassword, string newPassword);

        ///
        /// <summary>
        ///     Processes a request to update the password question and answer for a User
        ///     user.</summary>
        ///
        /// Parameters:
        ///   username:
        ///     The user to change the password question and answer for.
        ///
        ///   password:
        ///     The password for the specified user.
        ///
        ///   newPasswordQuestion:
        ///     The new password question for the specified user.
        ///
        ///   newPasswordAnswer:
        ///     The new password answer for the specified user.
        ///
        /// <returns>
        ///     true if the password question and answer are updated successfully; otherwise,
        ///     false.</returns>
        bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer);

        ///
        /// <summary>
        ///     Adds a new User user to the data source.</summary>
        ///
        /// Parameters:
        ///   username:
        ///     The user name for the new user.
        ///
        ///   password:
        ///     The password for the new user.
        ///
        ///   email:
        ///     The e-mail address for the new user.
        ///
        ///   passwordQuestion:
        ///     The password question for the new user.
        ///
        ///   passwordAnswer:
        ///     The password answer for the new user
        ///
        ///   isApproved:
        ///     Whether or not the new user is approved to be validated.
        ///
        ///   providerUserKey:
        ///     The unique identifier from the User data source for the user.
        ///
        ///   status:
        ///     A System.Web.Security.UserCreateStatus enumeration value indicating
        ///     whether the user was created successfully.
        ///
        /// <returns>
        ///     A System.Web.Security.IUser object populated with the information
        ///     for the newly created user.</returns>
        IUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out UserCreateException exception);

        ///
        /// <summary>
        ///     Removes a user from the User data source.</summary>
        ///
        /// Parameters:
        ///   username:
        ///     The name of the user to delete.
        ///
        ///   deleteAllRelatedData:
        ///     true to delete data related to the user from the database; false to leave
        ///     data related to the user in the database.
        ///
        /// <returns>
        ///     true if the user was successfully deleted; otherwise, false.</returns>
        bool DeleteUser(string username, bool deleteAllRelatedData);


        ///
        /// <summary>
        ///     Gets a collection of User users where the e-mail address contains the
        ///     specified e-mail address to match.</summary>
        ///
        /// Parameters:
        ///   emailToMatch:
        ///     The e-mail address to search for.
        ///
        ///   pageIndex:
        ///     The index of the page of results to return. pageIndex is zero-based.
        ///
        ///   pageSize:
        ///     The size of the page of results to return.
        ///
        ///   totalRecords:
        ///     The total number of matched users.
        ///
        /// <returns>
        ///     A list of IUser that contains a
        ///     page of pageSize IUser objects beginning at the
        ///     page specified by pageIndex.</returns>
        List<IUser> FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords);

        ///
        /// <summary>
        ///     Gets a collection of User users where the user name contains the specified
        ///     user name to match.</summary>
        ///
        /// Parameters:
        ///   usernameToMatch:
        ///     The user name to search for.
        ///
        ///   pageIndex:
        ///     The index of the page of results to return. pageIndex is zero-based.
        ///
        ///   pageSize:
        ///     The size of the page of results to return.
        ///
        ///   totalRecords:
        ///     The total number of matched users.
        ///
        /// <returns>
        ///     A list of IUser that contains a
        ///     page of pageSize IUser objects beginning at the
        ///     page specified by pageIndex.</returns>
        List<IUser> FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords);

        ///
        /// <summary>
        ///     Gets a collection of all the users in the data source in pages of data.</summary>
        ///
        /// Parameters:
        ///   pageIndex:
        ///     The index of the page of results to return. pageIndex is zero-based.
        ///
        ///   pageSize:
        ///     The size of the page of results to return.
        ///
        ///   totalRecords:
        ///     The total number of matched users.
        ///
        /// <returns>
        ///     A list of IUser that contains a
        ///     page of pageSize IUser objects beginning at the
        ///     page specified by pageIndex.</returns>
        List<IUser> GetAllUsers(int pageIndex, int pageSize, out int totalRecords);

        ///
        /// <summary>
        ///     Gets the number of users currently accessing the application.</summary>
        ///
        /// <returns>
        ///     The number of users currently accessing the application.</returns>
        int GetNumberOfUsersOnline();

        ///
        /// <summary>
        ///     Gets the password for the specified user name from the data source.</summary>
        ///
        /// Parameters:
        ///   username:
        ///     The user to retrieve the password for.
        ///
        ///   answer:
        ///     The password answer for the user.
        ///
        /// <returns>
        ///     The password for the specified user name.</returns>
        string GetPassword(string username, string answer);

        ///
        /// <summary>
        ///     Gets user information from the data source based on the unique identifier
        ///     for the User user. Provides an option to update the last-activity date/time
        ///     stamp for the user.</summary>
        ///
        /// Parameters:
        ///   providerUserKey:
        ///     The unique identifier for the User user to get information for.
        ///
        ///   userIsOnline:
        ///     true to update the last-activity date/time stamp for the user; false to return
        ///     user information without updating the last-activity date/time stamp for the
        ///     user.
        ///
        /// <returns>
        ///     An IUser object populated with the specified
        ///     user's information from the data source.</returns>
        IUser GetUser(object providerUserKey, bool userIsOnline);

        ///
        /// <summary>
        ///     Gets information from the data source for a user. Provides an option to update
        ///     the last-activity date/time stamp for the user.</summary>
        ///
        /// Parameters:
        ///   username:
        ///     The name of the user to get information for.
        ///
        ///   userIsOnline:
        ///     true to update the last-activity date/time stamp for the user; false to return
        ///     user information without updating the last-activity date/time stamp for the
        ///     user.
        ///
        /// <returns>
        ///     An IUser object populated with the specified
        ///     user's information from the data source.</returns>
        IUser GetUser(string username, bool userIsOnline);

        ///
        /// <summary>
        ///     Gets the user name associated with the specified e-mail address.</summary>
        ///
        /// Parameters:
        ///   email:
        ///     The e-mail address to search for.
        ///
        /// <returns>
        ///     The user name associated with the specified e-mail address. If no match is
        ///     found, return null.</returns>
        string GetUserNameByEmail(string email);

        ///
        /// <summary>
        ///     Raises the System.Web.Security.UserProvider.ValidatingPassword event
        ///     if an event handler has been defined.</summary>
        ///
        /// Parameters:
        ///   e:
        ///     The System.Web.Security.ValidatePasswordEventArgs to pass to the System.Web.Security.UserProvider.ValidatingPassword
        ///     event handler.
        void OnValidatingPassword(ValidatePasswordEventArgs e);

        ///
        /// <summary>
        ///     Resets a user's password to a new, automatically generated password.</summary>
        ///
        /// Parameters:
        ///   username:
        ///     The user to reset the password for.
        ///
        ///   answer:
        ///     The password answer for the specified user.
        ///
        /// <returns>
        ///     The new password for the specified user.</returns>
        string ResetPassword(string username, string answer);

        ///
        /// <summary>
        ///     Clears a lock so that the User user can be validated.</summary>
        ///
        /// Parameters:
        ///   userName:
        ///     The User user whose lock status you want to clear.
        ///
        /// <returns>
        ///     true if the User user was successfully unlocked; otherwise, false.</returns>
        bool UnlockUser(string userName);
        ///
        /// <summary>
        ///     Updates information about a user in the data source.</summary>
        ///
        /// Parameters:
        ///   user:
        ///     A System.Web.Security.IUser object that represents the user to update
        ///     and the updated information for the user.
        void UpdateUser(IUser user);

        ///
        /// <summary>
        ///     Verifies that the specified user name and password exist in the data source.</summary>
        ///
        /// Parameters:
        ///   username:
        ///     The name of the user to validate.
        ///
        ///   password:
        ///     The password for the specified user.
        ///
        /// <returns>
        ///     true if the specified username and password are valid; otherwise, false.</returns>
        bool ValidateUser(string username, string password);
    }


}
